package org.apache.mytest;

import org.apache.jmeter.JMeter;
import org.apache.jmeter.config.Argument;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.config.ConfigTestElement;
import org.apache.jmeter.control.CriticalSectionController;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.extractor.DebugPostProcessor;
import org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor;
import org.apache.jmeter.protocol.http.control.Header;
import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.reporters.Summariser;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.testelement.property.JMeterProperty;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree;
import org.apache.poi.ss.formula.functions.T;
import org.checkerframework.checker.units.qual.A;
import org.json.simple.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;

/**
 * @author guobingbing
 * @version 1.0
 * @wechat t_gbinb
 * @create 2021/6/2 15:04
 */
public class HTTPSamplerTest {

	/**
	 * 创建TestPlan
	 * @return
	 */
	public static TestPlan createTestPlan(){
		TestPlan testPlan = new TestPlan();
		testPlan.setName("测试计划");
		testPlan.setComment("云平台自动化测试");
		testPlan.setEnabled(true);
		testPlan.setFunctionalMode(false);
		testPlan.setTearDownOnShutdown(true);
		testPlan.setSerialized(true);
		return testPlan;
	}

	/**
	 * 创建线程组
	 *
	 * @return
	 */
	public static ThreadGroup createThreadGroup() {
		ThreadGroup threadGroup = new ThreadGroup();
		threadGroup.setName("Example Thread Group");
		threadGroup.setNumThreads(1);
		threadGroup.setRampUp(0);
		threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
		threadGroup.setScheduler(false);
		threadGroup.setDelay(0);
		return threadGroup;
	}

	/**
	 * 创建串行执行器
	 * @return
	 */
	public static CriticalSectionController createCriticalController(){
		CriticalSectionController controller = new CriticalSectionController();
		controller.setComment("接口串行执行");
		controller.setLockName("global_lock");
		controller.setProperty(TestElement.NAME, CriticalSectionController.class.getName());
		controller.initialize();
		return controller;
	}

	/**
	 * 创建循环控制器
	 *
	 * @return
	 */
	public static LoopController createLoopController() {
		// Loop Controller
		LoopController loopController = new LoopController();
		loopController.setLoops(1);
		loopController.setContinueForever(false);
		loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
		loopController.initialize();
		return loopController;
	}

	private static ConfigTestElement createConfigTestElement(){
		ConfigTestElement config = new ConfigTestElement();
		config.setName("HTTP请求默认值");
		config.setEnabled(true);
		config.setProperty(HTTPSamplerBase.PROTOCOL, "https");
		config.setProperty(HTTPSamplerBase.DOMAIN, "testapp.huanuo.co");
		config.setProperty(HTTPSamplerBase.PORT, "443");
		return config;
	}

	private static HTTPSamplerProxy createHTTPSamplerProxy(){
		HTTPSamplerProxy httpSamplerProxy = new HTTPSamplerProxy();

		HeaderManager headerManager = new HeaderManager();
		headerManager.add(new Header("Content-Type", "application/json"));
		headerManager.add(new Header("Authorization", "${token}"));
		httpSamplerProxy.setHeaderManager(headerManager);

		httpSamplerProxy.setProtocol("https");
		httpSamplerProxy.setPort(443);
		httpSamplerProxy.setDomain("testapp.huanuo.co");
		httpSamplerProxy.setMethod("POST");
		httpSamplerProxy.setConnectTimeout("5000");
		httpSamplerProxy.setUseKeepAlive(true);
		httpSamplerProxy.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
		return httpSamplerProxy;
	}

	/**
	 * 创建http采样器
	 *
	 * @return
	 */
	private static HTTPSamplerProxy sendSmsProxy() {
		HTTPSamplerProxy httpSamplerProxy = createHTTPSamplerProxy();
		httpSamplerProxy.setName("发送短信");
		httpSamplerProxy.setPath("/user/api/user/sendSms");
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("mobile", "18600783892");
		httpSamplerProxy.addNonEncodedArgument("", jsonObject.toJSONString(), "=");
		httpSamplerProxy.setPostBodyRaw(true);
		return httpSamplerProxy;
	}

	/**
	 * 用户登录注册
	 * @return
	 */
	public static HTTPSamplerProxy userRegisterProxy() {
		HTTPSamplerProxy httpSamplerProxy = createHTTPSamplerProxy();
		httpSamplerProxy.setPath("/user/api/user/register");
		httpSamplerProxy.setName("登录注册");

		JSONObject jsonObject = new JSONObject();
		jsonObject.put("mobile", "18600783892");
		jsonObject.put("smsCode", "666666");
		jsonObject.put("userAesKey", "ss4WLoR2pDqbUYYE");
		jsonObject.put("keyStatus", "1");
		httpSamplerProxy.addNonEncodedArgument("", jsonObject.toJSONString(), "=");
		httpSamplerProxy.setPostBodyRaw(true);
		return httpSamplerProxy;
	}

	/**
	 * 创建json处理器
	 * @return
	 */
	public static JSONPostProcessor createJsonProcessor(){
		JSONPostProcessor processor = new JSONPostProcessor();
		processor.setRefNames("data;status");
		processor.setJsonPathExpressions("$.data;$.status");
		processor.setMatchNumbers("1");
		processor.setDefaultValues("error;error");
		processor.setProperty(TestElement.TEST_CLASS, JSONPostProcessor.class.getName());
		return processor;
	}

	/**
	 * 自定义Processor
	 * @return
	 */
	public static MyEncDecProcessor createEncDecProcessor(){
		MyEncDecProcessor processor = new MyEncDecProcessor();
		processor.setProperty(TestElement.TEST_CLASS, MyEncDecProcessor.class.getName());
		return processor;
	}

	/**
	 * 添加调试器
	 * @return
	 */
	public static DebugPostProcessor createDebugProcessor(){
		DebugPostProcessor processor = new DebugPostProcessor();
		processor.setDisplayJMeterVariables(true);
		processor.setDisplaySamplerProperties(true);
		JMeterUtils.setLocale(Locale.CHINA);
		return processor;
	}

	private static void createTestPlan2(){
		// jemter 引擎
		StandardJMeterEngine engine = new StandardJMeterEngine();
		// 设置不适用gui的方式调用jmeter
		System.setProperty(JMeter.JMETER_NON_GUI, "true");
		// 设置jmeter.properties文件，我们将jmeter文件存放在resources中，通过classload
		String path = HTTPSamplerTest.class.getResource("/jmeter.properties").getPath();
		File jmeterPropertiesFile = new File(path);
		if (jmeterPropertiesFile.exists()) {
			JMeterUtils.loadJMeterProperties(jmeterPropertiesFile.getPath());
			HashTree testPlanTree = new HashTree();
			// 创建测试计划
			TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");

			// 创建循环控制器
			LoopController loopController = createLoopController();
			// 创建线程组
			ThreadGroup threadGroup = createThreadGroup();
			// 线程组设置循环控制
			threadGroup.setSamplerController(loopController);
			// 将测试计划添加到测试配置树中
			HashTree rootHashTree = testPlanTree.add(testPlan, threadGroup);

			/*==========接口请求===================*/
			HashTree httpPostHashTree = new HashTree();
			//发送验证码
			HTTPSamplerProxy sendSmsSampler = sendSmsProxy();

			httpPostHashTree.add(sendSmsSampler);


			//登录注册
			HTTPSamplerProxy registerSampler = userRegisterProxy();
			//解析结果中的内容
			JSONPostProcessor processor = createJsonProcessor();

			httpPostHashTree.add(registerSampler, processor);


			rootHashTree.add(httpPostHashTree);

			//增加结果收集
			Summariser summer = null;
			String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
			if (summariserName.length() > 0) {
				summer = new Summariser(summariserName);
			}
			ResultCollector logger = new ResultCollector(summer);
			testPlanTree.add(testPlanTree.getArray(), logger);
			logger.setFilename("F:/jmeter/test.jtl");
			//保存测试配置文件
			try {
				SaveService.saveTree(testPlanTree, new FileOutputStream("F:/jmeter/test.jmx"));
			} catch (IOException e) {
				e.printStackTrace();
			}

			// 配置jmeter
			engine.configure(testPlanTree);
			// 运行
			engine.run();

			SampleResult httpResult = registerSampler.sample();

			System.out.println(httpResult.getResponseMessage());
			System.out.println(httpResult.getResponseDataAsString());
		}
	}

	private static void createTestPlan3(){
		// jemter 引擎
		StandardJMeterEngine engine = new StandardJMeterEngine();
		// 设置不适用gui的方式调用jmeter
		System.setProperty(JMeter.JMETER_NON_GUI, "true");
		String jmeterPropPath = HTTPSamplerTest.class.getResource("/jmeter.properties").getPath();
		JMeterUtils.loadJMeterProperties(jmeterPropPath);

		HashTree threadChildTree = new ListedHashTree();
//		CriticalSectionController criticalController = createCriticalController();
//		threadChildTree.add(criticalController);

		//发送短信
		HTTPSamplerProxy sendSmsSampler = sendSmsProxy();
		threadChildTree.add(sendSmsSampler);

		//登录注册
		ListedHashTree registerProcessorTree = new ListedHashTree();
		JSONPostProcessor regJsonProcessor = createJsonProcessor();
		registerProcessorTree.add(regJsonProcessor);
		MyEncDecProcessor encDecProcessor = createEncDecProcessor();
		registerProcessorTree.add(encDecProcessor);
		DebugPostProcessor debugPostProcessor = createDebugProcessor();
		registerProcessorTree.add(debugPostProcessor);

		HTTPSamplerProxy registerSampler = userRegisterProxy();
		threadChildTree.add(registerSampler, registerProcessorTree);

		ThreadGroup threadGroup = createThreadGroup();
		LoopController loopController = createLoopController();
		threadGroup.setSamplerController(loopController);

		HashTree threadGroupTree = new ListedHashTree();
		threadGroupTree.add(threadGroup, threadChildTree);

		HashTree planRootTree = new ListedHashTree();
		TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
		planRootTree.add(testPlan, threadGroupTree);

		//增加结果收集
		Summariser summer = null;
		String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
		if (summariserName.length() > 0) {
			summer = new Summariser(summariserName);
		}
		ResultCollector logger = new ResultCollector(summer);
		planRootTree.add(planRootTree.getArray(), logger);
		logger.setFilename("F:/jmeter/test3.csv");
		//保存测试配置文件
		try {
			JMeterUtils.setProperty("saveservice_properties", HTTPSamplerTest.class.getResource("/saveservice.properties").getPath());
			SaveService.saveTree(planRootTree, new FileOutputStream("F:/jmeter/test3.jmx"));
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 配置jmeter
		engine.configure(planRootTree);
		// 运行
		engine.run();
	}

	private static void createTestPlan4(){
		// jemter 引擎
		StandardJMeterEngine engine = new StandardJMeterEngine();
		// 设置不适用gui的方式调用jmeter
		System.setProperty(JMeter.JMETER_NON_GUI, "true");
		String jmeterPropPath = HTTPSamplerTest.class.getResource("/jmeter.properties").getPath();
		JMeterUtils.loadJMeterProperties(jmeterPropPath);



		ListedHashTree rootTree = new ListedHashTree();

		TestPlan testPlan = createTestPlan();

		ThreadGroup threadGroup = createThreadGroup();
		LoopController loopController = createLoopController();
		threadGroup.setSamplerController(loopController);

		ListedHashTree groupChildTree = new ListedHashTree();
		ConfigTestElement configTestElement = createConfigTestElement();
		groupChildTree.add(configTestElement);
		groupChildTree.add(sendSmsProxy());

		ListedHashTree groupTree = new ListedHashTree();
		groupTree.add(threadGroup, groupChildTree);

		rootTree.add(testPlan, groupTree);

		//增加结果收集
		Summariser summer = null;
		String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
		if (summariserName.length() > 0) {
			summer = new Summariser(summariserName);
		}
		ResultCollector logger = new ResultCollector(summer);
		rootTree.add(rootTree.getArray(), logger);
		logger.setFilename("F:/jmeter/test4.csv");
		//保存测试配置文件
		try {
			JMeterUtils.setProperty("saveservice_properties", HTTPSamplerTest.class.getResource("/saveservice.properties").getPath());
			SaveService.saveTree(rootTree, new FileOutputStream("F:/jmeter/test4.jmx"));
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 配置jmeter
		engine.configure(rootTree);
		// 运行
		engine.run();
	}

	public static void main(String[] args) throws IOException {
		createTestPlan4();
	}
}
